package com.springcloud.sc.ucpv5.client.application.message.connect;

import java.util.concurrent.Callable;

import com.springcloud.sc.ucpv5.client.application.message.DataMessageManager;
import com.springcloud.sc.ucpv5.client.application.message.MessageService;
import com.springcloud.sc.ucpv5.client.application.message.MessageServiceException;
import com.springcloud.sc.ucpv5.client.application.util.Constant;
import com.springcloud.sc.ucpv5.client.common.CmdDefine;
import com.springcloud.sc.ucpv5.client.commondata.SecuResult;
import com.springcloud.sc.ucpv5.client.commondata.data.HertHandleMsg;
import com.springcloud.sc.ucpv5.client.commondata.data.LoginRsp;
import com.springcloud.sc.ucpv5.client.commondata.data.MsgHeader;
import com.springcloud.sc.ucpv5.client.module.datamanager.LoginDataManager;
import com.springcloud.sc.ucpv5.client.util.DateToolUtil;
import com.springcloud.sc.ucpv5.client.util.PublicUtil;
import com.springcloud.sc.ucpv5.client.util.ThreadUtil;

public class ShakeHandThread {

	/**
	 * 握手线程停止标志
	 */
	int shakeHandSpace;
	int shakeHandCount;

	public ShakeHandThread() {
		shakeHandSpace = 5 * 1000;
		// 跟后台通讯握手连续失败次数达到这个设置值，则退出前台系统
		shakeHandCount = 3;
	}

	private RunThread runThread;

	class RunThread {
		boolean shakeHandsStop = false;

		public boolean isShakeHandsStop() {
			return shakeHandsStop;
		}

		public void setShakeHandsStop(boolean shakeHandsStop) {
			this.shakeHandsStop = shakeHandsStop;
		}

		public void communicationShakeHands() {
			if (Constant.CORBA_CONNECTION) {
				Thread.currentThread().setName("ShakeHandsThread");
				int shakeCount = 0;
				int code = 0;

				shakeHandsStop = false;

				try {
		    Thread.sleep(shakeHandSpace);
				} catch (Exception e) {
					// TODO: handle exception
				}

				while (!isShakeHandsStop()) {
					try {
						code = shakeHand();
						if (code == MessageService.ERROR_CODE_SOCKET_SHUTDOWN || code == MessageService.ERROR_CODE_SESSION_ERROR) {
							shakeCount = shakeHandCount;
						}
						if (code != 0) {
							// 握手失败,更新状态栏
							if (shakeCount == 0) {
								;
							}
							shakeCount++;
						} else {
							;
							shakeCount = 0;
						}
					} catch (Exception exp) {
						shakeCount++;
					}
					if (shakeCount >= shakeHandCount) {
						shakeHandTime = 0;
						MessageService.getInstance().setSessionValid(false);
						break;
					}

					try {
						Thread.sleep(shakeHandSpace);
					} catch (InterruptedException e) {
						e.printStackTrace();

					}
				}

				if (true) {
					// 不弹出对话框,直接后台自动重新登录
					startAutoLogin();
					return;
				}
			}
		}
	}

	public void beginShakeHands() {
		if (runThread != null && !runThread.isShakeHandsStop()) {
			runThread.setShakeHandsStop(true);
			runThread = null;
		}

		Callable<Object> call = new Callable<Object>() {
			public Object call() throws Exception {
				try {
					runThread = new RunThread();
					runThread.communicationShakeHands();
				} catch (Exception e) {
					// TODO: handle exception
				}
				return null;
			}
		};
		ThreadUtil.getInstance().Call(call);
	}

	public void stop() {
		if (runThread != null && !runThread.isShakeHandsStop()) {
			runThread.setShakeHandsStop(true);
			runThread = null;
		}
	}

	private long shakeHandTime = 0;

	public void setShakeHandTime(long shakeHandTime) {
		this.shakeHandTime = shakeHandTime;
	}

	public int shakeHand() {
		return shakeHand(0);
	}

	/**
	 * 通讯握手
	 * 
	 * @date 2006-7-21
	 * @return
	 * @throws MessageServiceException
	 * @see
	 */
	public int shakeHand(int reason) {
		final MsgHeader header = MessageService.getInstance().getMessageHeader(PublicUtil.nullToShort(Constant.MODULE_FRAMEWORK_ID), CmdDefine.CMD_COMMUNICATION_SHAKEHAND, "", null);

		final HertHandleMsg holder = new HertHandleMsg();
		holder.UserName = LoginDataManager.getInstance().getName();
		holder.UserTelno = LoginDataManager.getInstance().getUserTelphone();
		holder.UserName = null == holder.UserName ? "" : holder.UserName;
		holder.UserTelno = null == holder.UserTelno ? "" : holder.UserTelno;
		holder.reason = reason;

	if (reason == 0 && shakeHandTime != 0) {
	    // 比较当前发送握手时间与上次握手成功返回的间隔
	    long time = System.currentTimeMillis();
	    if ((time - shakeHandTime) > shakeHandSpace*2) {
	    	System.out.println("!!!!!!!!!!!出现超时 超时间隔 :" + (time - shakeHandTime) + " 当前时间: " + DateToolUtil.getCurTime());
		// 发送握手时间
		int ret = MessageService.getInstance().internalSendASyncMsg(header, holder);
		// 5*2 秒表示出现超时
		return MessageService.ERROR_CODE_TRANSFER_FAIL;
	    }
	} else if (reason == 2) {
	    // 记录握手成功时间
	    shakeHandTime = System.currentTimeMillis();
	    return 0;
		} else if (reason == 0 && shakeHandTime == 0) {
			// 比较当前发送握手时间与上次握手成功返回的间隔
			shakeHandTime = System.currentTimeMillis();
		}
		int ret = MessageService.getInstance().internalSendASyncMsg(header, holder);
		return ret;
	}

	public static void startAutoLogin() {
		// 启动连接线程
		Callable<Object> call = new Callable<Object>() {
			public Object call() throws Exception {
				while (true) {
					try {
						LoginDataManager currentUser = LoginDataManager.getInstance();

						boolean connect = true;
						if (Constant.CORBA_CONNECTION) {
							System.out.println("尝试重连服务器");
							int retCode = DataMessageManager.getInstance().initMessageService(MessageService.getInstance().getCurrentIP(), MessageService.getInstance().getCurrentPort());
							if (SecuResult.RET_SUCCEED != retCode) {
								System.out.println("尝试重连服务器, 连接失败");
								connect = false;
							}
						}
						if (connect) {
							System.out.println("自动连接服务器后, 重新发送登录请求");
							SecuResult result = new SecuResult();
							LoginRsp rsp = DataMessageManager.getInstance().LoginSystem(currentUser.getName(), currentUser.getPassWord(), result, true, true);
							if (rsp != null && rsp.Result == 0) {
								System.out.println("自动连接服务器后, 登录成功");
								return null;
							} else {
								System.out.println("自动连接服务器后, 登录失败:" + rsp.Result);
							}
						}
						Thread.sleep(5 * 1000);
					} catch (Exception e) {
						// TODO 自动生成 catch 块
						e.printStackTrace();
						return null;
					}
				}
			}
		};

		ThreadUtil.getInstance().Call(call);
	}
}
